package user;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.TreeMap;

/**
 * 角色基础
 * 
 */
public class User {

    int mId; // 角色标识
    int mRoomId; // 当前所在房间
    Socket mSock; // 连接符类
    // int mScore = 12222; // 身上拥有积分
    boolean mRobot = false; // 是否机器人

    Map<Integer, BetData> bets = new TreeMap<>(); // 押注区索引(0开始)-->数据

    UserMgr mUserMgr; // 角色管理器

    /**
     * 初始化角色:登录时or创建机器人
     * 
     * @param id
     * @param sock
     */
    public User(UserMgr um, int id, int sock, boolean robot) {
        mUserMgr = um;
        mId = id;
        mRobot = robot;
    }

    public void setRoom(int roomId) {
        mRoomId = roomId;
    }

    public int getRoomID() {
        return mRoomId;
    }

    public boolean isRobot() {
        return mRobot;
    }

    public int getID() {
        return mId;
    }

    /**
     * 角色退出游戏
     */
    public boolean onLogout() {
        boolean b = mUserMgr.delUser(this);
        if (!b) {
            System.err.printf("user logout, id:%d\n", this.mId);
            return false;
        }
        return b;
    }

    /**
     * 记录押注
     * 
     * @param idx   押注区索引:0~7
     * @param score 积分
     */
    public boolean bet(Integer idx, int ratio, Integer score) {
        /*
         * if (score > mScore) {
         * System.out.printf("user bet, score not enough:%d, %d\n", score, mScore);
         * return false;
         * }
         */

        BetData bd = bets.computeIfAbsent(idx, k -> new BetData(idx, ratio));
        if (bd == null || bd.getRatio() == 0) {
            // 不应该走到这里
            // ub = new BetData(score);
            // bets.put(idx, ub);
            System.err.println("*********************** user bet, err");
            return false;
        }
        bd.add(score);
        // mScore -= score;
        System.out.printf("user bet, robot:%b, id:%d, roomId:%d, idx:%d, ratio:%d, score:%d\n",
                isRobot(), mId, mRoomId, idx, ratio, score);

        // todo 保存数据库...

        return true;
    }

    /**
     * 发送消息(模拟) 真正使用的地方 请替换接口
     * 
     * @param msg
     */
    public void send(String msg) {
        try {
            if (isRobot()) { // 机器人不推送
                return;
            }
            System.out.printf(">>>>>>>>>> user send msg:%d, %s\n", mId, msg);

            DataOutputStream out = new DataOutputStream(mSock.getOutputStream());
            out.writeUTF(msg);
        } catch (SocketTimeoutException e) {
            // TODO: handle exception
            System.err.printf("send timeout, user:%d\n", mId);
        } catch (IOException e) {
            // TODO: handle exception
            System.err.printf("send ipexp, user:%d\n", mId);
        } catch (Exception e) {
            // TODO: handle exception
            System.err.printf("send exp, user:%d\n", mId);
        }
    }

    // ==================================================================================
    public void testBet() {
        bet(0, 11, 1);
        bet(1, 12, 3);
        bet(5, 13, 1);
        bet(12, 14, 5);
        bet(3, 15, 3);
        bet(7, 16, 1);

        showBet();
    }

    public void showBet() {
        System.out.printf("user:%d bets:%d\n", mId, bets.size());
        bets.forEach((k, v) -> {
            // a
            v.calcScore();
            System.out.printf("--------- idx:%d, data:%s\n", k, v.info());
        });
    }
}
